package com.surfilter.risk.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.surfilter.cloud.elasticsearch.ElasticSearchProvider;
import com.surfilter.risk.entity.Page;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.UnknownHostException;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * ElasticsearchUtils
 * Dis:es的工具类
 * Created by grom on 2017/5/11.
 */
public class ElasticsearchUtils {
    private static Logger logger = LoggerFactory.getLogger(ElasticsearchUtils.class);
    private static TransportClient client = null;

    private static ResourceBundle bundle = ResourceBundle.getBundle("elasticsearch-config");
    private static String CLUSTER_NAME = bundle.getString("cluster.name");
    private static String CLIENT_TRANSPORT_SNIFF = bundle.getString("client.transport.sniff");
    private static String CLIENT_NODE_ADDRESS = bundle.getString("client.node.address");
    private static String CLIENT_HTTP_PORT = bundle.getString("client.http.port");
    static {
        init();
    }

    public static TransportClient init() {
        try {
            client = new ElasticSearchProvider().getSearchClient(CLUSTER_NAME,
                                                                CLIENT_NODE_ADDRESS,
                                                                Boolean.parseBoolean(CLIENT_TRANSPORT_SNIFF),
                                                                Integer.parseInt(CLIENT_HTTP_PORT));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return client;
    }

    /**
     * term查询返回第一条记录
     *
     * @param index
     * @param type
     * @param queryBuilder
     * @return
     */
    public static JSONObject getTermQueryFirst(String index, String type, BoolQueryBuilder queryBuilder) {
        JSONObject json = new JSONObject();
        SearchResponse response = client.prepareSearch(index)
                .setTypes(type)
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(queryBuilder)
                .execute()
                .actionGet();
        SearchHits searchHits = response.getHits();
        if (searchHits.getHits().length <= 0) return null;
        json = JSONObject.parseObject(searchHits.getAt(0).getSourceAsString());
        return json;
    }

    /**
     * term查询返回第一条记录
     *
     * @param index
     * @param type
     * @param queryBuilder
     * @return
     */
    public static JSONObject getTermQueryFirst(String index, String type, QueryBuilder queryBuilder) {
        try {
            SearchResponse response = client.prepareSearch(index)
                    .setTypes(type)
                    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                    .setQuery(queryBuilder)
                    .execute()
                    .actionGet();
            SearchHits searchHits = response.getHits();
            if (searchHits.getHits().length <= 0) return new JSONObject();
            return JSONObject.parseObject(searchHits.getAt(0).getSourceAsString());
        } catch (Exception e) {
            logger.info("ES select first data error ");
            return new JSONObject();
        }
    }

    /**
     * 分页查询
     * @param index
     * @param type
     * @param queryBuilder
     * @param clazz
     * @param pageSize
     * @param pageNo
     * @return
     */
    public static Page findByPage(String index, String type, QueryBuilder queryBuilder,
                                  Class clazz,
                                  Integer pageSize,
                                  Integer pageNo) {
        Page page = new Page();
        pageNo = null == pageNo ? 1 : pageNo;
        pageNo = 0 >= pageNo ? 1 : pageNo;
        page.setPageNumber(pageNo);
        page.setPageSize(pageSize);

        Client client = init();
        SearchRequestBuilder srb = client.prepareSearch(index);
        srb.setTypes(type);
        srb.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
        srb.setQuery(queryBuilder);
        // 设置是否按查询匹配度排序
//        srb.setExplain(true);
        srb.setFrom((pageNo - 1) * pageSize).setSize(pageSize)
                .setExplain(true);

        SearchResponse response = srb.execute().actionGet();
        SearchHits hits = response.getHits();

        page.setTotalRow((int) hits.getTotalHits());
        Gson gson = new Gson();
        for (SearchHit searchHit : hits) {
            Map source = searchHit.getSource();
//            page.getList().add(source);
            page.getList().add(gson.fromJson(gson.toJson(source), clazz));
        }
        page.setTotalPage(page.getTotalPage());
        return page;
    }

    /**
     * 分页查询
     * @param index
     * @param type
     * @param queryBuilder
     * @param clazz
     * @param pageSize
     * @param pageNo
     * @return
     */
    public static Page findByPageWithHightLight(String index, String type, QueryBuilder queryBuilder,
                                  Class clazz,
                                  Integer pageSize,
                                  Integer pageNo) {

        HighlightBuilder highlightBuilder = new HighlightBuilder().field("*").requireFieldMatch(false);
        highlightBuilder.preTags("<span style=\"color:red\">");
        highlightBuilder.postTags("</span>");

        Page page = new Page();
        pageNo = null == pageNo ? 1 : pageNo;
        pageNo = 0 >= pageNo ? 1 : pageNo;
        page.setPageNumber(pageNo);
        page.setPageSize(pageSize);

        Client client = init();
        SearchRequestBuilder srb = client.prepareSearch(index);
        srb.setTypes(type);
        srb.highlighter(highlightBuilder);
        srb.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
        srb.setQuery(queryBuilder);
        // 设置是否按查询匹配度排序
//        srb.setExplain(true);
        srb.setFrom((pageNo - 1) * pageSize).setSize(pageSize)
                .setExplain(true);

        SearchResponse response = srb.execute().actionGet();
        SearchHits hits = response.getHits();

        page.setTotalRow((int) hits.getTotalHits());
        Gson gson = new Gson();
        for (SearchHit searchHit : hits) {
            Map source = searchHit.getSource();
//            page.getList().add(source);
            page.getList().add(gson.fromJson(gson.toJson(source), clazz));
        }
        page.setTotalPage(page.getTotalPage());
        return page;
    }

    public static void testFacet(String index, String type, QueryBuilder queryBuilder, String typeFacetStr) {
        Client client = init();
        TermsAggregationBuilder tradeAggregationBuilder = AggregationBuilders.terms("tradeListSum")
                .field("industryType")
                .size(Integer.MAX_VALUE);
        TermsAggregationBuilder positionAggregationBuilder = AggregationBuilders.terms("positionListSum")
                .field("provence")
                .size(Integer.MAX_VALUE);
        TermsAggregationBuilder compstateAggregationBuilder = AggregationBuilders.terms("compstateListSum")
                .field("businessStatus")
                .size(Integer.MAX_VALUE);
//        tradeAggregationBuilder.subAggregation(positionAggregationBuilder);
//        tradeAggregationBuilder.subAggregation(compstateAggregationBuilder);


        SearchResponse response = client.prepareSearch(index)
                .setTypes(type)
                .setQuery(queryBuilder)
                .addAggregation(tradeAggregationBuilder)
                .addAggregation(positionAggregationBuilder)
                .addAggregation(compstateAggregationBuilder)
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .execute()
                .actionGet();

        Terms tradeTerms = response.getAggregations().get("tradeListSum");
        Terms positionTerms = response.getAggregations().get("positionListSum");
        Terms compstateTerms = response.getAggregations().get("compstateListSum");

        if (tradeTerms != null) {
            for (Terms.Bucket entry : tradeTerms.getBuckets()) {
                System.out.println(entry.getKey() + "--" + entry.getDocCount());
            }
        }
        if (positionTerms != null) {
            for (Terms.Bucket entry : positionTerms.getBuckets()) {
                System.out.println(entry.getKey() + "--" + entry.getDocCount());
            }
        }
        if (compstateTerms != null) {
            for (Terms.Bucket entry : compstateTerms.getBuckets()) {
                System.out.println(entry.getKey() + "--" + entry.getDocCount());
            }
        }

        client.close();
    }

    public static void main(String[] args) {
        String [] keyWords = new String[]{"市"};
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        for(int i=0;i<keyWords.length;i++){
            boolQueryBuilder
                    .should(QueryBuilders.termQuery("ename", keyWords[i]))
                    .should(QueryBuilders.termQuery("businessScope", keyWords[i]))
                    .should(QueryBuilders.termQuery("address", keyWords[i]));
        }
//        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        testFacet("qixin20170517","businessInfo",boolQueryBuilder,"");


//        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
//
//        Page page = findByPage("qixin20170517", "punish", matchAllQueryBuilder,
//                PunishWithBLOBs.class,
//                1,
//                1);
//        System.out.println(page);
    }
}
